#!/usr/bin/python3
# -*- coding:utf-8 -*-
""""
@Author: 李吉凯
@Email: lijk34925@hundsun.com
@Time: 2022/6/13 14:39
@File: table_new.py
"""
import re
import time

from qturboframe.lib.utils.by import By
from qturboframe.lib.webdriver import SeleniumError
from qturboframe.public_ui.h_ui.refactor_table import RefactorTable
from qturboframe.lib.webdriver.remote.webdriver import WebDriver
from qturboframe.lib.webdriver.remote.webelement import WebElement
from qturboframe.public_ui.base_element import BaseElement

from BladeFerm.Lib.Common import logger
from BladeFerm.hui12_common.function import display_wait
from BladeFerm.hui2_app.hui2_lib.button import Button


class NewTable(RefactorTable):

    def __init__(self, element_para, father=None, timeout=10, index=1):
        # 因为表格内容加载缓慢，所以先判断一下。表格的行是否加载完成，之后再进行查找会跟稳定点
        display_wait(idname={By.CSS_SELECTOR: 'table>tbody.h-table-tbody>tr.h-table-row'}, flag=0,
                     timeout=timeout, driver=father)
        # element_para入参为字符串类型时，默认为查询方式为id
        if isinstance(element_para, dict) and By.TEXT in element_para:
            text = element_para.get(By.TEXT)
            # xpath = ".//table//*[contains(normalize-space(text()),'{}')]//ancestor::div[contains(@class,'h-table-wrapper')][1]".format(text)
            # xpath = ".//table//*[contains(normalize-space(text()),'{}')]//ancestor::table".format(text)
            xpath = ".//table//*[contains(normalize-space(text()),'{}')]//ancestor::div[contains(@class,'h-table-wrapper')]//table".format(
                text)
            element_para = {By.XPATH: xpath}

        if isinstance(element_para, str):
            element_para = {By.ID: element_para}
        if isinstance(element_para, WebElement):
            self._element = element_para
            self._driver = element_para._parent
            self.timeout = timeout
        elif not isinstance(element_para, dict):
            raise AttributeError('element_para参数类型不正确！')
        else:
            if father is None:
                raise AttributeError('未定位元素，father参数不能为None！')
            if isinstance(father, WebDriver):
                self._driver = father
                self.timeout = timeout
            elif isinstance(father, WebElement):
                self._driver = father._parent
                self.timeout = timeout
            else:
                raise AttributeError('father参数类型不正确！')
            key_list = [By.ID, By.NAME, By.CLASS_NAME, By.TAG_NAME, By.LINK_TEXT,
                        By.PARTIAL_LINK_TEXT, By.CSS_SELECTOR, By.XPATH]
            element_by = ''
            element_value = ''
            assist = ''
            for key, value in element_para.items():
                if key in key_list:
                    element_by = key
                    element_value = value
                else:
                    assist += '{}:{},'.format(key, value)
            assist = assist.strip(',')
            # self._elements = father.find_elements_by_attribute(
            #     element_by, element_value, assist, self.timeout)
            # logger.info(f'self._elements: {self._elements}')
            exception_msg = ""
            for i in range(4):
                try:
                    self._elements = father.find_elements_by_attribute(
                        element_by, element_value, assist, self.timeout)
                    logger.debug(f'self._elements : {self._elements}')
                    self.header_tables = []
                    self.body_tables = []
                    self.header_fixeds = []
                    self.header_right_fixeds = []
                    self.body_fixeds = []
                    self.body_right_fixeds = []
                    self.fixed_header = None
                    self.fixed_right_header = None
                    self.fixed_body = None
                    self.fixed_right_body = None
                    self.table_body = None
                    self.unfixed_header = None
                    # 获取到头table和身体table
                    for i, temp in enumerate(self._elements):
                        # if BaseElement(temp).get_text().strip()!='' and temp.is_displayed():
                        if temp.is_displayed():
                            father_element = temp.find_element_by_attribute("xpath", "..")
                            element_class = father_element.get_attribute("class").split(' ')
                            logger.debug(f'element_class: {element_class}')
                            if "h-table-header" in element_class:
                                self.header_tables.append(temp)
                            elif "h-table-body" in element_class:
                                self.body_tables.append(temp)
                            elif 'h-simple-content' in element_class:
                                if 'h-table-body' in father_element.find_element_by_attribute('xpath',
                                                                                        "..").get_attribute('class'):
                                    self.body_tables.append(temp)
                            elif 'h-table-fixed-header' in element_class:
                                t = father_element.find_element_by_xpath("..")
                                c = t.get_attribute("class")
                                if 'h-table-fixed-right' in c:
                                    self.header_right_fixeds.append(temp)
                                else:
                                    self.header_fixeds.append(temp)
                            elif 'h-table-fixed-body' in element_class:
                                t = father_element.find_element_by_xpath("..")
                                c = t.get_attribute("class")
                                if 'h-table-fixed-right' in c:
                                    self.body_right_fixeds.append(temp)
                                else:
                                    self.body_fixeds.append(temp)
                    break
                except Exception as e:
                    logger.warning(f'查找表格相关元素出现异常 {e}')
                    time.sleep(1.0)
            else:
                logger.error(exception_msg)
                raise SeleniumError("表格查找失败!")

            if self.header_tables and len(self.header_tables)>0:
                self.table_header = self.header_tables[index-1]
            else:
                if self.body_tables and len(self.body_tables)>0:
                    self.table_header = self.body_tables[index-1]
            if self.body_tables and len(self.body_tables) > 0:
                self.table_body = self.body_tables[index-1]

            if self.header_right_fixeds and len(self.header_right_fixeds)>0:
                self.fixed_right_header = self.header_right_fixeds[index-1]

            if self.header_fixeds and len(self.header_fixeds)>0:
                self.fixed_header = self.header_fixeds[index-1]

            if self.body_right_fixeds and len(self.body_right_fixeds) > 0:
                self.fixed_right_body = self.body_right_fixeds[index - 1]

            if self.body_fixeds and len(self.body_fixeds) > 0:
                self.fixed_body = self.body_fixeds[index - 1]

            self.__get_pagination()
            self.__go_to_first_page()
            self.__get_toolbar()

    def check(self, header_content, expect_data, select_all=False, page_limit=4):
        '''
        根据列名和列名信息查找BOP的表格中所在的行数,字典key为table为列名，字典值为table为内容，然后查找expect_data中key指定的列的内容

        :Args:
         - header_content: 字典类型，为table的某一header名和某一行的内容组成的字典例如：{'指令序号': '1311', '回溯状态': '正常'}
         - expect_data: 字典类型
         - select_all: bool类型，是否查找所有符合条件的行数。默认False，表示查找第一行。
         - page_limit: ini类型，表示最大翻页次数。默认最大翻页次数为4次，可以翻到第5页
        :Returns:
            返回查找的某一行所有元素,类型为List<WebElement>

        :Raises:
            SeleniumError: 表格行数查找失败

        :Example:
         - 例: table.get_table_row({'指令序号': '1311', '回溯状态': '正常'})
        '''
        logger.info("检查表格数据开始")
        fixed_table_title_list = []
        table_title_list = self.__get_table_titles()  # 得到table的header
        # if self.fixed_header and BaseElement(self.fixed_header).get_text() != '':
        if self.fixed_header and BaseElement(self.fixed_header).element.get_attribute('innerText') != '':
            fixed_table_title_list = self.__get_fixed_table_titles()

        expected_rows = self._get_expected_rows(header_content, select_all, page_limit)

        logger.debug(f'expected_rows: {expected_rows}')
        for expected_row in expected_rows:
            row_index, page_no = expected_row[0], expected_row[1]
            if self.pagination:
                self.__go_to_target_page(page_no)

            # 检查内容
            fail = False
            for expect_key, expect_value in expect_data.items():

                if expect_key in table_title_list:
                    check_index = table_title_list.index(expect_key) + 1
                    is_fixed = False
                elif expect_key in fixed_table_title_list:
                    check_index = fixed_table_title_list.index(expect_key) + 1
                    is_fixed = True
                else:
                    raise SeleniumError("没有找到表头:{}".format(expect_key))

                xpath = ".//tr[{}]/td[{}]".format(row_index,check_index)
                cell = None
                if is_fixed:
                    cell = self.fixed_body.find_element_by_attribute(By.XPATH, xpath)
                else:
                    cell = self.table_body.find_element_by_attribute(By.XPATH, xpath)
                if cell.text.strip() != expect_value.strip():
                    fail = True
                logger.info("{}行，‘{}’列中期望的值为：{}, 实际的值为：{}".format(row_index, expect_key, expect_value, cell.text))
            if fail:
                raise SeleniumError("校验失败")

        logger.info("检查表格数据结束")

    def click_cell(self, input_data: dict, click_input: dict, select_all=False):
        '''
        根据列名和列名信息查找BOP的表格中所在的行数,字典key为table为列名，字典值为table为内容，然后点击click_input指定的cell的表格

        :Args:
         - header_content: 字典类型，为table的某一header名和某一行的内容组成的字典例如：{'指令序号': '1311', '回溯状态': '正常'}

        :Returns:
            返回查找的某一行所有元素,类型为List<WebElement>

        :Raises:
            SeleniumError: 表格行数查找失败

        :Example:
         - 例: table.click_cell({'指令序号': '1311', '回溯状态': '正常'},{"操作":"查看用户"})
        '''
        logger.info("点击表格单元格开始")
        expected_rows = self._get_expected_rows(input_data, select_all=select_all)
        row_index = expected_rows[0][0]
        page_no = expected_rows[0][1]
        if self.pagination:
            self.__go_to_target_page(page_no)
            pass

        click_header = None
        click_button_text = None
        for k, v in click_input.items():
            click_header = k
            click_button_text = v

        header_titles = self.__get_table_titles()
        fixed_header_titles = self.__get_fixed_table_titles()
        fixed_right_header_titles = self.__get_fixed_right_table_titles()

        click_header_tag = "fixed_header"
        column_index = -1
        if click_header in header_titles:
            click_header_tag = "header"
            column_index = header_titles.index(click_header) + 1
        elif click_header in fixed_header_titles:
            click_header_tag = "fixed_header"
            column_index = fixed_header_titles.index(click_header) + 1
        elif click_header in fixed_right_header_titles:
            click_header_tag = "fixed_right_header"
            column_index = fixed_right_header_titles.index(click_header) + 1

        if click_header_tag == "fixed_header":
            locator = ".//tr[{}]//td[{}]//ancestor::tr".format(row_index,column_index)
            element = self.fixed_body.find_element_by_attribute(By.XPATH, locator, timeout=self.timeout)
            Button({By.TEXT: click_button_text}, element, timeout=self.timeout).js_click()
            logger.info("点击表格第{}行的“{}”单元格".format(row_index, click_button_text))
        elif click_header_tag == "fixed_right_header":
            locator = ".//tr[{}]//td[{}]//ancestor::tr".format(row_index,column_index)
            element = self.fixed_right_body.find_element_by_attribute(By.XPATH, locator, timeout=self.timeout)
            Button({By.TEXT: click_button_text}, element, timeout=self.timeout).js_click()
            logger.info("点击表格第{}行的“{}”单元格".format(row_index, click_button_text))
        elif click_header_tag == "header":
            locator = ".//tr[{}]//td[{}]//ancestor::tr".format(row_index,column_index)
            element = self.table_body.find_element_by_attribute(By.XPATH, locator, timeout=self.timeout)
            Button({By.TEXT: click_button_text}, element, timeout=self.timeout).js_click()
            logger.info("点击表格第{}行的“{}”单元格".format(row_index, click_button_text))
        else:
            raise SeleniumError("没有找到要点击的单元格")
        logger.info("点击表格单元格结束")

    def refresh(self):
        # 点击导出图标，展开下拉选择
        btn_exp_icon = self.toolbar.find_element_by_attribute('xpath',
                                                              './/i[contains(@class,"h-icon-refresh")]//ancestor::button')
        btn_exp_icon.click()
        logger.info(f'点击 刷新 图标')

    def export(self, is_all=True, rows=None, button_name_new=None):
        '''
        导出表格数据。
        :param is_all: 是否导出全部行
        :param rows: 导出指定行时，给出导出的行的筛选条件。字典类型：{'指令序号': '1311', '回溯状态': '正常'}
        :param button_name_new: 可用新的名称，替换默认的名称。例如：全量导出，当前导出
        :return:
        '''
        if is_all:
            button_name = '导出全部行'
        else:
            button_name = '导出选中行'
            self.select_row(rows, select_all=False)
        button_name = button_name_new if button_name_new else button_name
        time.sleep(0.5)
        # self.__get_toolbar()
        # 点击导出图标，展开下拉选择
        btn_exp_icon = self.toolbar.find_element_by_attribute('xpath',
                                                         './/i[contains(@class,"icon-upload1")]//ancestor::button')
        btn_exp_icon.click()
        logger.info(f'点击 导出 图标')
        # 点击 导出xx
        btn_exp = self.toolbar.find_element_by_attribute(By.XPATH, './/li[@class="h-dropdown-item"]/button',
                                                          'text:' + button_name)
        btn_exp.click()

    def export_second(self, is_all=True, rows=None, button_type_name=None):
        '''
        导出表格数据。导出按钮，有
        :param is_all: 是否导出全部行
        :param rows: 导出指定行时，给出导出的行的筛选条件。字典类型：{'指令序号': '1311', '回溯状态': '正常'}
        :param button_name_new: 可用新的名称，替换默认的名称。例如：全量导出，当前导出
        :return:
        '''
        if is_all:
            button_name = '全量导出'
        else:
            button_name = '当前导出'
        button_name = button_type_name if button_type_name else button_name
        time.sleep(0.5)
        # self.__get_toolbar()
        # 点击导出图标，展开下拉选择
        # btn_exp_icon = self.toolbar.find_element_by_attribute('xpath',
        #                                                       '(.//div[@class="h-datagrid-toolbar"]//button)[2]')
        btn_exp_icon = Button({'text': '导出'}, father=self.toolbar)
        btn_exp_icon.click()
        logger.info(f'点击 导出 图标')
        # 点击 导出xx
        btn_exp = self.toolbar.find_element_by_attribute(By.XPATH, './/li[@class="h-dropdown-item"]',
                                                         f'text:{button_name}')
        btn_exp.click()

    def set_col_name(self, names=None):
        '''
        设置表格显示的列。
        :param names: 要取消的列名
        :return:
        '''
        display_cols = []
        if not isinstance(names, list):
            names = names.split(',')
        if not names:
            logger.warning(f'没有要取消显示的列，按照默认列显示。')
            return False
        # 点击 设置 图标，展开下拉选择
        btn_set = self.toolbar.find_element_by_attribute('xpath', './/i[contains(@class, "h-icon-t-b-setting")]//ancestor::button')
        if btn_set:
            btn_set.click()
            logger.info(f'点击 设置 图标')
        else:
            raise SeleniumError(f'没有找到 设置 图标！')
        # 勾选显示列
        labels = self.toolbar.find_elements_by_attribute(By.CSS_SELECTOR, 'div.h-checkbox-group>label.h-checkbox-group-item')
        for lab in labels:
            text = lab.text
            if text in names:
                lab.click()
                logger.info(f'取消 {text} 列的显示！')
            else:
                display_cols.append(text)
        logger.info(f'显示的列名：{display_cols}')
        if btn_set:
            btn_set.click()
        return display_cols

    def get_rows_in_page(self):
        '''
        获取表格页显示的行数

        :Return:
            返回表格页显示的行数

        :Example:
         - 例: page.get_rows_in_page()
        '''
        rows_div = self.pagination.exist(
            'css selector', 'span.h-page-total',
            timeout=self.timeout)
        if rows_div:
            rows_text = rows_div.text
            rows = int(re.search(r'\d+', rows_text).group())
            return rows
        else:
            return 0

    def get_title_list(self):
        return self.__get_table_titles()  # 得到table的header

    def select_row(self, header_content: dict, select_all=False):
        '''
        根据列名和列名信息查找BOP的表格中所在的行数,字典key为table为列名，字典值为table为内容

        :Args:
         - header_content: 字典类型，为table的某一header名和某一行的内容组成的字典例如：{'指令序号': '1311', '回溯状态': '正常'}

        :Returns:
            返回查找的某一行所有元素,类型为List<WebElement>

        :Raises:
            SeleniumError: 表格行数查找失败

        :Example:
         - 例: table.get_table_row({'指令序号': '1311', '回溯状态': '正常'})
        '''
        logger.info("选择表格数据开始")
        #取消所有的选中
        if self.fixed_header:
            locator = "span.h-checkbox"
            span_checkbox = self.fixed_header.exist(By.CSS_SELECTOR, locator)
            if span_checkbox:
                locator = "input[type='checkbox']"
                checkbox = span_checkbox.find_element_by_attribute(By.CSS_SELECTOR, locator)
                if 'h-checkbox-checked' in span_checkbox.get_attribute("class"):
                    self._driver.execute_script("arguments[0].click();", checkbox)
                else:
                    # 先使全选中
                    self._driver.execute_script("arguments[0].click();", checkbox)
                    # 再取消选中
                    self._driver.execute_script("arguments[0].click();", checkbox)

        expected_rows = self._get_expected_rows(header_content, select_all=select_all)

        page_no_temp = 0
        for row in expected_rows:
            row_index = row[0]
            page_no = row[1]
            logger.info("目标数据在第{}页，第{}行".format(page_no, row_index))
            if self.pagination and page_no != page_no_temp:
                self.__go_to_target_page(page_no)
                page_no_temp = page_no
            if self.fixed_body and len(expected_rows)>1:
                xpath = ".//tr[{}]//input[@type='checkbox']".format(row_index)
                checkbox = self.fixed_body.find_element_by_attribute(By.XPATH, xpath, timeout=1)
                self._driver.execute_script("arguments[0].click();", checkbox)
            elif self.fixed_body and self.fixed_body.get_attribute("innerText").replace("\t","").replace("\n","")!="":
                xpath = ".//tr[{}]//input[@type='checkbox']".format(row_index)
                checkbox = self.fixed_body.find_element_by_attribute(By.XPATH, xpath, timeout=1)
                self._driver.execute_script("arguments[0].click();", checkbox)
            else:
                xpath = ".//tbody/tr[{}]".format(row_index)
                tr = self.table_body.find_element_by_attribute(By.XPATH, xpath, timeout=1)
                tr.click()
                time.sleep(0.2)
                # todo: 循环点击时，点击下一个，上一个会取消？不知道是啥bug？
        # res_dic = self.__change_data(expected_rows)
        # for page_no, rows in res_dic.items():
        #     self.__go_to_target_page(page_no)
        #     trs = self.table_body.find_elements_by_attribute(By.XPATH, ".//tbody/tr", timeout=1)
        #     for i in range(len(trs)):
        #         if i+1 in rows:
        #             trs[i].click()
        #         time.sleep(1)
        logger.info("选择表格数据结束")

    def foucs_cell(self, input_data:dict, click_input:dict, select_all=False):
        '''
        根据列名和列名信息查找BOP的表格中所在的行数,字典key为table为列名，字典值为table为内容，然后点击click_input指定的cell的表格

        :Args:
         - header_content: 字典类型，为table的某一header名和某一行的内容组成的字典例如：{'指令序号': '1311', '回溯状态': '正常'}

        :Returns:
            返回查找的某一行所有元素,类型为List<WebElement>

        :Raises:
            SeleniumError: 表格行数查找失败

        :Example:
         - 例: table.click_cell({'指令序号': '1311', '回溯状态': '正常'},{"操作":"查看用户"})
        '''
        logger.info("点击表格单元格开始")
        expected_rows = self._get_expected_rows(input_data, select_all=select_all)
        row_index = expected_rows[0][0]
        page_no = expected_rows[0][1]
        if self.pagination:
            self.__go_to_target_page(page_no)
            pass

        click_header = None
        click_button_text = None
        for k, v in click_input.items():
            click_header = k
            click_button_text = v

        header_titles = self.__get_table_titles()
        fixed_header_titles = self.__get_fixed_table_titles()
        fixed_right_header_titles = self.__get_fixed_right_table_titles()

        click_header_tag = "fixed_header"
        column_index = -1
        if click_header in header_titles:
            click_header_tag="header"
            column_index = header_titles.index(click_header) + 1
        elif click_header in fixed_header_titles:
            click_header_tag = "fixed_header"
            column_index = fixed_header_titles.index(click_header) + 1
        elif click_header in fixed_right_header_titles:
            click_header_tag = "fixed_right_header"
            column_index = fixed_right_header_titles.index(click_header) + 1

        if click_header_tag=="fixed_header":
            locator = ".//tr[{}]//td[{}]//ancestor::tr".format(row_index,column_index)
            element = self.fixed_body.find_element_by_attribute(By.XPATH, locator, timeout=self.timeout)
            Button({By.TEXT:click_button_text}, element, timeout=self.timeout).element.move_to()
            logger.info("聚焦表格第{}行的“{}”单元格".format(row_index, click_button_text))
        elif click_header_tag=="fixed_right_header":
            locator = ".//tr[{}]//td[{}]//ancestor::tr".format(row_index, column_index)
            element = self.fixed_right_body.find_element_by_attribute(By.XPATH, locator, timeout=self.timeout)
            Button({By.TEXT:click_button_text}, element, timeout=self.timeout).element.move_to()
            logger.info("聚焦表格第{}行的“{}”单元格".format(row_index, click_button_text))
        else:
            raise SeleniumError("没有找到要聚焦的单元格")
        logger.info("聚焦表格单元格结束")

    def __change_data(self, expected_rows):
        '''
        数据个数变换
        :param expected_rows: [(row_index, page_no),(row_index, page_no),(row_index, page_no)]
        :return:
        '''
        res_dic = dict()
        for index, page in expected_rows:
            cur_page_list = res_dic.get(page, [])
            cur_page_list.append(index)
            res_dic.update({page: cur_page_list})
        return res_dic

    def check_rows_reload_finish(self, timeout=10):
        '''
        判定表格行数是否加载完成
        :return:
        '''
        if self.table_body:
            return display_wait(idname={By.CSS_SELECTOR: 'tr.h-table-row'}, flag=0, timeout=timeout, driver=self.table_body)
        else:
            return False


    def __get_toolbar(self):
        '''
        获取表格上方的功能按钮栏
        :return:
        '''
        locator = './/ancestor::*[contains(@class,"h-datagrid")]/div[contains(@class,"h-datagrid-toolbar")]'
        if self.table_body:
            self.toolbar = self.table_body.exist(By.XPATH, locator, timeout=1)
        elif self.table_header:
            self.toolbar = self.table_header.exist(By.XPATH, locator, timeout=1)
        else:
            self.toolbar = None
        logger.info(f'toolbar: {self.toolbar}')

    def _get_expected_rows(self, header_content, select_all=False, page_limit=4):
        '''
        根据表头和表格值组成的字典进行查找。
        :param header_content:
        :param select_all:
        :param page_limit: 最大翻页次数。默认为4，能翻到第5页
        :return: [(row_index, page_no)]  查找到符合条件的数据行和所在分页
        '''
        self.__go_to_target_page(1)

        expected_rows=[]

        query_header_indexes = []
        query_contents = []
        fixed_table_title_list = []
        fixed_right_table_title_list = []
        table_title_list = self.__get_table_titles()  # 得到table的header
        if self.fixed_header and BaseElement(self.fixed_header).element.get_attribute('innerText') != '':
            fixed_table_title_list = self.__get_fixed_table_titles()

        if self.fixed_right_header and BaseElement(self.fixed_right_header).element.get_attribute('innerText') != '':
            fixed_right_table_title_list = self.__get_fixed_right_table_titles()

        for key, value in header_content.items():
            if key in table_title_list:
                query_header_indexes.append((table_title_list.index(key) + 1, ""))  # 得到要查找的header在第几列
                query_contents.append(value)
            elif len(fixed_table_title_list) != 0 and key in fixed_table_title_list:
                query_header_indexes.append((fixed_table_title_list.index(key) + 1, "fixed_table"))  # 得到要查找的header在第几列
                query_contents.append(value)
            elif len(fixed_right_table_title_list) != 0 and key in fixed_right_table_title_list:
                query_header_indexes.append((fixed_right_table_title_list.index(key) + 1, "fixed_right_table"))  # 得到要查找的header在第几列
                query_contents.append(value)
            else:
                raise SeleniumError("没有找到表头：{}".format(key))
        find = False
        finished = False
        cur_page = 1
        while True:
            # 用多列查找时，查找的第一个内容
            first_query_content = query_contents[0]
            td_xpath = ".//tbody/tr/td[{}]".format(query_header_indexes[0][0])
            tds = []
            if query_header_indexes[0][1] == "fixed_table":
                tds = self.fixed_body.find_elements_by_attribute(By.XPATH, td_xpath, timeout=0.2)
            elif query_header_indexes[0][1] == "fixed_right_table":
                tds = self.fixed_body.find_elements_by_attribute(By.XPATH, td_xpath, timeout=0.2)
            else:
                tds = self.table_body.find_elements_by_attribute(By.XPATH, td_xpath, timeout=0.2)
            content_list = self.__get_tds_text(tds)
            logger.debug(f'content_list： {content_list}')
            #查找的可能是多列数据例如{"指令序号":"51,52"}
            if first_query_content.split(',')[0] in content_list:
                # 先找到和第一个内容匹配的行
                # row_indexes = [index + 1 for index, value in enumerate(content_list) if value == first_query_content]
                row_indexes = [index + 1 for index, value in enumerate(content_list) if value in first_query_content.split(',')]
                logger.debug(f'row_indexes: {row_indexes}')        # 元素所在的行数列表
                for row_index in row_indexes:
                    td = None
                    for index, value in enumerate(query_header_indexes):
                        xpath = ".//tbody/tr[{}]/td[{}]".format(row_index, value[0])
                        td = None
                        if value[1] == "fixed_table":
                            td = self.fixed_body.find_element_by_attribute(By.XPATH, xpath, timeout=1)
                        else:
                            td = self.table_body.find_element_by_attribute(By.XPATH, xpath, timeout=1)
                        td_cls = BaseElement(td).element.get_attribute('innerText').strip()
                        # logger.debug(f'td_cls : {td_cls}')
                        if td_cls in query_contents[index].split(','):
                            pass
                        else:
                            break
                    else:
                        find = True
                        finished = True
                        page_no = 0
                        if self.pagination:
                            #获取到页数
                            page_no = self.__get_current_page()

                        expected_rows.append((row_index, page_no))
                        if select_all:
                            #找到所有的
                            finished = False
                        else:
                            break

            if finished:
                break

            logger.debug(f'pagination： {self.pagination}')
            if not self.pagination:
                # 没有分页标签时
                break

            if find:   # 只要当前页找到符合条件的数据，就不再往后翻页了。避免数据太多，无限翻下去。没啥意义。
                break
            else:
                if cur_page > page_limit:
                    raise SeleniumError(f"当前页码为{cur_page}，限制最大翻页次数为：{page_limit}。"
                                        f"若还未找到请检查过滤条件是否正确，或放开翻页次数限制。")
                # 进入下一页
                if not self.__go_to_next_page():
                    if not find:
                        raise SeleniumError("在当前页面没有找到此{}内容的行".format(header_content))
                    break
                else:
                    cur_page += 1
                time.sleep(0.5)  # 翻页后等待元素加载后，再查询列名方能生效。
        if not find:
            raise SeleniumError("没有找到符合要求的行:{}".format(header_content))

        return expected_rows

    def __get_fixed_header_body(self):
        '''
        获取冻结列表格头,非冻结列表格头,表格体
        '''
        if not self.table_body:
            return

        locator = ".//ancestor::div[contains(@class,'h-table-wrapper')]//*[contains(@class,'h-table-fixed-header')]//table"
        temps = self.table_body.find_elements_by_attribute(By.XPATH, locator, timeout=1)
        for temp in temps:
            if temp.is_displayed():
                self.fixed_header = temp
                break

        locator = ".//ancestor::div[contains(@class,'h-table-wrapper')]//*[contains(@class,'h-table-fixed-body')]//table"
        temps = self.table_body.find_elements_by_attribute(By.XPATH, locator, timeout=1)
        for temp in temps:
            if temp.is_displayed():
                self.fixed_body = temp
                break

        locator = ".//ancestor::div[contains(@class,'h-table-wrapper')]//*[contains(@class,'h-table-header')]//table"
        temps = self.table_body.find_elements_by_attribute(By.XPATH, locator, timeout=1)
        for temp in temps:
            if temp.is_displayed():
                self.unfixed_header = temp
                break

    def __get_pagination(self):
        locator = './/ancestor::div[contains(@class,"h-datagrid")]//ul[contains(@class,"h-page")]'
        if self.table_body:
            self.pagination = self.table_body.exist(By.XPATH, locator, timeout=1)
        elif self.table_header:
            self.pagination = self.table_header.exist(By.XPATH, locator, timeout=1)
        else:
            self.pagination = None
        logger.debug(f'self.pagination: {self.pagination}')

    def __go_to_pre_page(self):
        locator = "li[title='上一页']"
        next_page = self.pagination.find_element_by_attribute(By.CSS_SELECTOR, locator, timeout=self.timeout)
        if "h-page-disabled" in next_page.get_attribute("class"):
            # 已经到了第一页
            return False
        self._driver.execute_script("arguments[0].click();", next_page)
        return True

    def __go_to_next_page(self):
        locator = "li[title='下一页']"
        next_page = self.pagination.find_element_by_attribute(By.CSS_SELECTOR, locator, timeout=self.timeout)
        if "h-page-disabled" in next_page.get_attribute("class"):
            # 已经到了最后一页
            return False
        self._driver.execute_script("arguments[0].click();", next_page)
        return True

    def __get_current_page(self):
        if self.pagination:
            locator = "li.h-page-item-active"
            current_page = self.pagination.find_element_by_attribute(By.CSS_SELECTOR, locator, timeout=self.timeout)
            page_no = int(current_page.get_attribute("title"))
            return page_no
        return 0

    def __go_to_target_page(self, page_no):
        if self.pagination:
            if page_no == 0:
                # 没有分页操作的table
                pass
            else:
                if page_no == 1:
                    locator = "ul.h-page li[title='{}']".format(page_no)
                    first_page = self.pagination.find_element_by_attribute(By.CSS_SELECTOR, locator)
                    first_page.click()
                else:
                    # 在分页中有些页面会在....中

                    # 获取到当前所在的页面
                    current_page_no = self.__get_current_page()
                    if page_no > current_page_no:
                        for i in range(page_no - current_page_no):
                            self.__go_to_next_page()
                    elif page_no < current_page_no:
                        for i in range(current_page_no - page_no):
                            self.__go_to_pre_page()
                    else:
                        # 不用跳转页面
                        pass

    def __go_to_first_page(self):
        if self.pagination:
            locator = "li[title='1']"
            first_page = self.pagination.find_element_by_attribute(By.CSS_SELECTOR, locator, timeout=self.timeout)
            self._driver.execute_script("arguments[0].click();", first_page)

    def __get_table_titles(self):
        """
        获取table的header
        """
        # table中有thead标签
        title_td_xpath = ".//thead/tr/th"
        tds = self.table_header.find_elements_by_attribute(By.XPATH, title_td_xpath, timeout=0.1)
        # 有的table没有thead标签
        if len(tds) == 0:
            title_td_xpath = ".//tr[1]/td"
            tds = self.table_header.find_elements_by_attribute(By.XPATH, title_td_xpath, timeout=0.1)
        title_list = []
        for td in tds:
            # title_list.append(BaseElement(td).get_text().replace("\n","").replace("\t","").strip())
            title_list.append(
                BaseElement(td).element.get_attribute('innerText').replace("\n", "").replace("\t", "").strip())
        return title_list

    def __get_fixed_table_titles(self):
        """
        获取table的header
        """
        if self.fixed_header:
            # table中有thead标签
            title_td_xpath = ".//thead/tr/th"
            tds = self.fixed_header.find_elements_by_attribute(By.XPATH, title_td_xpath, timeout=0.1)
            # 有的table没有thead标签
            if len(tds) == 0:
                title_td_xpath = ".//tr[1]/td"
                tds = self.fixed_header.find_elements_by_attribute(By.XPATH, title_td_xpath, timeout=0.1)
            title_list = []
            for td in tds:
                title_list.append(
                    BaseElement(td).element.get_attribute('innerText').replace("\n", "").replace("\t", "").strip())
            return title_list
        return []

    def __get_fixed_right_table_titles(self):
        """
        获取table的header
        """
        if self.fixed_right_header:
            # table中有thead标签
            title_td_xpath = ".//thead/tr/th"
            tds = self.fixed_right_header.find_elements_by_attribute(By.XPATH, title_td_xpath, timeout=0.1)
            # 有的table没有thead标签
            if len(tds) == 0:
                title_td_xpath = ".//tr[1]/td"
                tds = self.fixed_right_header.find_elements_by_attribute(By.XPATH, title_td_xpath, timeout=0.1)
            title_list = []
            for td in tds:
                title_list.append(
                    BaseElement(td).element.get_attribute('innerText').replace("\n", "").replace("\t", "").strip())
            return title_list
        return []

    def __get_tds_text(self, tds):
        text_list = []
        for td in tds:
            # text_list.append(BaseElement(td).get_text())
            text_list.append(BaseElement(td).element.get_attribute('innerText'))
        return text_list